
 2019最后一天 各位小伙伴加油啊 本周作业（12.30-1.12）
 本周作业内容如下：假设小偷有一个背包，最多能装20公斤赃物，
#他闯入一户人家，发现如下表所示的物品。很显然，他不能把所有物品都装进背包，所以必须确定拿走哪些物品，
 留下哪些物品。
#名称价格（美元）重量（kg）
#电脑      200 20
#收音机    20 4
 钟        175 10
#花瓶      50 2
 书        10 1
#油画      90 9


#这次作业 是阿里巴巴与四十大盗---背包问题一样。
#是用一种贪婪策略去实现的
#一个贪心算法总是做出当前最好的选择，也就是说，它期望通过局部最优选择从而得到全局最优的解决方案

此题尝试用贪心策略 包含如下
每次挑选价值最大的
2每次挑选重量最小的
3每次挑单位重量价值最大的宝物  也就是性价比
比较三个策略 第三种方法应该比较好

```python
import numpy as np
原有的字典: 美元 重量
old_dic = {'电脑': [200, 20], '收音机': [20, 4], '钟': [ 175, 10], '花瓶': [50, 2], '书': [10, 1], '油画': [90, 9]}
 根据性价比获得的新字典 : 美元 重量 性价比
new_dic = {'电脑': [200, 20, 10], '收音机': [20, 4, 5], '钟': [ 175, 10, 17.5], '花瓶': [50, 2, 25], '书': [10, 1, 10], '油画': [90, 9, 10]}

temp_old_dic = [[200, 20], [20, 4], [175, 10], [50, 2], [10, 1], [90, 9]]
背包问题解决方案类
class BagSolution:

    '''
    这次作业 是阿里巴巴与四十大盗---背包问题一样。
    是用一种贪婪策略去实现的# 一个贪心算法总是做出当前最好的选择，也就是说，它期望通过局部最优选择从而得到全局最优的解决方案
    此题尝试用贪心策略 包含如下
    1每次挑选价值最大的
    2每次挑选重量最小的
    3每次挑单位重量价值最大的宝物  也就是性价比
    比较三个策略 第三种方法应该比较好

    '''

    def __init__(self, dic: dict,bagWeight):
       self.dic = dic
       self.bagWeight = bagWeight

    # 每次挑选价值最大的
    def valueMax(self,index):

        #字典排序 
        if index == 1:
            tempidct = sorted(new_dic.items(),key = lambda item:item[1][0],reverse = True)      
        elif index == 2:
            tempidct = sorted(new_dic.items(),key = lambda item:item[1][1])  
        elif index == 3:
            tempidct = sorted(new_dic.items(),key = lambda item:item[1][2],reverse = True)
            # print(tempidct)
        print('*' * 50)
        tempWeight = 0
        tempValue = 0
        for i in range(len(tempidct)):

            tempWeight += tempidct[i][1][1] 
           
            if self.bagWeight - tempWeight >= 0 :
                tempValue += tempidct[i][1][0]
            else:
                tempWeight -= tempidct[i][1][1] 
                continue

            print('拿了{}价值{}重量{} '.format(tempidct[i][0],tempidct[i][1][0],tempidct[i][1][1]))
       
 
        print('一共背了{}kg'.format(tempWeight))
        print('一共背了价值{}美元的货物'.format(tempValue))

    '''
    动态规划的方式 把0-1背包问题解决的
    动态规划就是把原问题分解为若干子问题，先解决最小的问题，把结果存到表中
    再求解大问题

    '''
    def valueMax1(self):
        # i 表示几件物品
        # j 表示背包重量
        tempBagWeight = 0
        matrix = np.zeros((len(old_dic),self.bagWeight),dtype=np.int32)                                                               # 列出所有的可能 
        # print(matrix)
        for i in range(len(old_dic)):                                                                                                 #列出从1件物品到最大物品
            for j in range(self.bagWeight+1):
                if j > temp_old_dic[i][1]:                               
                    matrix[i][j-1] = max(matrix[i-1][j-1],matrix[i-1][j-1-temp_old_dic[i][1]] + temp_old_dic[i][0])                   #每件物品装到背包最佳值
                elif j == temp_old_dic[i][1]:
                    matrix[i][j-1] =  temp_old_dic[i][0]                                                                              # 如果装不下, 那就相当于没有这个物品
                else:
                    matrix[i][j-1] =  0
            # print('拿了{}价值{}重量{} '.format(old_dic[i][0],old_dic[i][1][0],old_dic[i][1][1]))

        print(matrix)      
        print(matrix[-1][-1])





b = BagSolution(new_dic,20)
b.valueMax(1)       #方案1
b.valueMax(2)       #方案2
b.valueMax(3)       #方案3

b.valueMax1()
```

#打印之后  发现20kg的背包 第三个方案拿的价值最高
# 故 一共背了17kg一共背了价值255美元的货物 是近似最优解
**************************************************
拿了电脑价值200重量20
一共背了20kg
一共背了价值200美元的货物
**************************************************
拿了书价值10重量1
拿了花瓶价值50重量2
拿了收音机价值20重量4
拿了油画价值90重量9
一共背了16kg
一共背了价值170美元的货物
**************************************************
拿了花瓶价值50重量2
拿了钟价值175重量10
拿了书价值10重量1
拿了收音机价值20重量4
一共背了17kg
一共背了价值255美元的货物
# 价值275美元的货物 最优解
[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0 200]
 [  0   0   0  20  20  20  20  20  20  20  20  20  20  20  20  20  20  20
   20 200]
 [  0   0   0   0   0   0   0   0   0 175 175 175 175 195 195 195 195 195
  195 200]
 [  0  50  50  50  50  50  50  50  50 175 175 225 225 225 225 245 245 245
  245 245]
 [ 10  50  60  60  60  60  60  60  60 175 185 225 235 235 235 245 255 255
  255 255]
 [  0   0   0   0   0   0   0   0  90 175 185 225 235 235 235 245 255 255
  265 275]]
275

"""
注意下格式代码格式哈,可以参考下尹路的同学的那个。
"""

